package cn.ts.utils;

import cn.ts.annotation.RateLimit;
import cn.ts.aspect.AbstractRateLimiter;
import cn.ts.entity.RateLimiterEntity;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.ExecutionException;

/**
 * @description
 * @create: 2025/3/10 15:01
 */
@Slf4j
@Component("redisRateLimiter")
public class RedisRateLimiter extends AbstractRateLimiter {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private ILimiterRepository repository;


    // 黑名单过期时间
    private final Duration BLACKLIST_TTL = Duration.of(24, ChronoUnit.HOURS);
    // lua 脚本内容
    private String luaScriptContent;

    @Override
    protected boolean limit(RateLimiterEntity rateLimiterEntity)  {
        RateLimit rateLimit = rateLimiterEntity.getRateLimit();
        String key = rateLimiterEntity.getKey();
        String userId = rateLimiterEntity.getUserId();

        // 获取限流时间（秒）
        int time = rateLimit.time();
        // 获取限流次数
        int count = rateLimit.count();

        // 获取或创建限流器
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);  // 基于令牌桶算法实现 userId为Key
        // 初始化限流器：设置速率和容量
        rateLimiter.trySetRate(RateType.OVERALL, count, time, RateIntervalUnit.SECONDS);

        // 尝试获取一个令牌
        boolean acquired = rateLimiter.tryAcquire(1);
        if (!acquired) {
            // 如果获取令牌失败，增加用户的违规次数
            repository.incrementViolationCount(userId);
            RMap<String, Integer> blacklistMap = redissonClient.getMap("blacklist");
            System.out.println("用户" + userId + "违规次数增加"+blacklistMap.get(userId));
            return true; // 限流
        }
        return false; // 未限流

    }

    @Override
    protected boolean blacklistCheck(RateLimiterEntity rateLimiterEntity) throws ExecutionException {
        String userId = rateLimiterEntity.getUserId();
        log.info("userId的限流次数:{}",repository.getViolationCount(userId));
        // 检查用户是否在黑名单中
        if (repository.getViolationCount(userId) >= 6.0) {

            return true;
        }
        return false; // 未限流
    }
}